<script lang="ts">
import type { Component } from 'vue';
import { useElementSize } from '@peng_kai/kit/libs/vueuse';
import { useTemplateRefs } from '@peng_kai/kit/vue';
import PwaTipbar from '~/pages/help/pwa-instruction/Tipbar.vue';
import Suspension from '~/pages/promo/pack/components/Suspension.vue';
import AsideMenuFull from './aside-menu/FullMenu.vue';
import AsideMenuSimple from './aside-menu/SimpleMenu.vue';
import BottomNav from './bottom-nav/index.vue';
import LayoutFooter from './footer/index.vue';
import LayoutHeader from './header/index.vue';
import { useLayout } from './useLayout';
import { useMainBreakpoint } from './useMainBreakpoint';

const Notify = defineAsyncComponent(() => import('~comp-b/notify/Notify.vue'));
</script>

<script setup lang="ts">
const { refs, setRefs } = useTemplateRefs<{
  header: HTMLElement;
  leftAside: Component;
  rightAside: HTMLElement;
  bottomNav: Component;
}>();
const headerSize = reactive(useElementSize(() => refs.header, undefined, { box: 'border-box' }));
const leftAsideSize = reactive(useElementSize(() => refs.leftAside?.$el.parentElement, undefined, { box: 'border-box' }));
const rightAsideSize = reactive(useElementSize(() => refs.rightAside, undefined, { box: 'border-box' }));
const bottomNav = reactive(useElementSize(() => refs.bottomNav?.$el, undefined, { box: 'border-box' }));
const [setMainEle] = useMainBreakpoint();

const { asideMenu, asideContent } = useLayout();
const cssVars = computed(() => ({
  '--left-aside-width': (asideMenu.opened && typeof asideMenu.state.footprint === 'number')
    ? `${asideMenu.state.footprint}px`
    : '',
  '--right-aside-width': (asideContent.drawerOpened && typeof asideContent.state.footprint === 'number')
    ? `${asideContent.state.footprint}px`
    : '',
}));

const { currentRoute } = useRouter();
</script>

<template>
  <div class="app-layout" :style="{ ...cssVars }">
    <header :ref="setRefs.header" class="header [grid-area:header] sticky top-0 z-10">
      <PwaTipbar />
      <LayoutHeader />
    </header>

    <main :ref="setMainEle" class="main [grid-area:main] relative">
      <RouterView :key="`${String(currentRoute.path)}-${toValue(appValues?.routeKey)}`" />
    </main>

    <footer class="footer [grid-area:footer] mt-25 flex items-center justify-center bg-sys-layer-b lt-mobile:mt-4">
      <LayoutFooter />
    </footer>

    <!-- 底部导航栏 -->
    <nav class="relative z-10 tabletl:hidden" :style="{ height: `${bottomNav.height}px` }">
      <BottomNav :ref="setRefs.bottomNav" class="bottom-nav fixed bottom-0" />
    </nav>

    <!-- 侧边菜单栏 -->
    <ADrawer
      :open="asideMenu.drawerOpened" class="!bg-sys-layer-a"
      rootClassName="layout-drawer side-menu-drawer" placement="left" width="auto"
      :closable="false" :getContainer="false"
      :mask="asideMenu.mode === asideMenu.state.open && asideMenu.state.mask"
      @close="asideMenu.toggle()"
    >
      <AsideMenuFull v-if="asideMenu.mode === 'full'" :ref="setRefs.leftAside" @close="asideMenu.toggle()" />
      <AsideMenuSimple v-if="asideMenu.mode === 'simple'" :ref="setRefs.leftAside" @close="asideMenu.toggle()" />
    </ADrawer>

    <!-- 侧边内容栏 -->
    <ADrawer
      :open="asideContent.drawerOpened"
      rootClassName="layout-drawer" placement="right" width="auto"
      :closable="false" :getContainer="false"
      :mask="asideContent.state.mask"
      @close="asideContent.toggle()"
    >
      <div
        :ref="(el: any) => setRefs.rightAside(asideContent.drawerOpened ? el : null)"
        class="h-full" :style="{ width: $bp.ltMobile ? 'calc(100vw - var(--scrollbar-width))' : '400px' }"
      >
        <KeepAlive>
          <Notify
            v-if="asideContent.type === 'notification'"
            class="notify-shadow box-border h-full bg-sys-layer-c p-3 pb-0"
            @close="asideContent.toggle()"
          />
        </KeepAlive>
        <div v-if="asideContent.type === 'leaderboard'">
          {{ $t('diUIbJkvWasrA129ajeIq') }}
        </div>
      </div>
    </ADrawer>

    <!-- 充值促销活动 -->
    <Suspension />
  </div>
</template>

<style lang="scss" scoped>
.app-layout {
  --header-height: calc(v-bind('headerSize.height') * 1px);
  --left-aside-width: calc(v-bind('leftAsideSize.width') * 1px);
  --right-aside-width: calc(v-bind('rightAsideSize.width') * 1px);
  --bottom-nav-height: calc(v-bind('bottomNav.height') * 1px);
  --main-base-margin: 16px;

  @media bp-lt-tablet {
    --main-base-margin: 12px;
  }
}

.left-aside,
.right-aside {
  position: fixed;
  top: var(--header-height);
  height: calc(var(--dfvh) - var(--header-height));
}

.header {
  box-shadow: 0px 6px 10px 0px rgba(0, 0, 0, 0.3);
}

.main {
  margin: var(--main-base-margin);
  margin-left: calc(var(--left-aside-width) + var(--main-base-margin));
  margin-right: calc(var(--right-aside-width) + var(--main-base-margin));
  min-height: calc(var(--dfvh) - var(--header-height));
  // padding-bottom: calc(var(--bottom-nav-height) + var(--main-base-margin));
  transition: margin 200ms;

  @media bp-lt-tablet {
    margin-left: var(--main-base-margin);
    margin-right: var(--main-base-margin);
  }

  // 当 main 下的子元素含有 main-auto-height 时，则 main 的最小高度自适应
  &:has(> .main-auto-height) {
    min-height: initial;
  }
}

.notify-shadow {
  box-shadow: 0px 20px 20px 0px rgba(0, 0, 0, 0.3);
}

.bottom-nav {
  position: fixed;
  padding-bottom: env(safe-area-inset-bottom);

  @at-root :root.ios & {
    padding-bottom: 15px;
    box-shadow: 0 40px 0 0 theme('colors.sys.layer.a');
  }
}

.footer {
  margin-left: var(--left-aside-width);
  margin-right: var(--right-aside-width);
  padding: 0 30px;
}

:deep(.layout-drawer) {
  position: fixed;
  z-index: 5;
  top: var(--header-height);
  bottom: var(--bottom-nav-height);

  .ant-drawer-content {
    display: flex;
    flex-direction: column;
    background-color: theme('colors.sys.layer.a');
  }

  .ant-drawer-wrapper-body {
    flex: 1;
  }

  .ant-drawer-body {
    padding: 0;
    // scrollbar-gutter: stable;
    scrollbar-width: none;
  }

  .ant-drawer-footer {
    margin-top: auto;
  }
}
</style>
